import type { DeleteParams, PaginationParam, PaginationResult, SearchModel } from "./models";
import req from "./req";
import { RequestMethodEnum } from "./req/httpEnum";

export interface CURDApiOptions {
  //获取所有数据URL，不分页
  getDataUrl?: string;
  getDataMethod?: RequestMethodEnum;
  //获取分页数据URL
  getPageUrl?: string;
  getPageMethod?: RequestMethodEnum;
  //获取详细信息,目前只支持根据对应主键id获取，即参数是{[idKey]: idValue}
  getDetailUrl?: string;
  getDetailMethod?: RequestMethodEnum;
  //增删改统一一个URL，利用post delete put区分
  cudUrl?: string;
  //增删改各对应一个URL
  createUrl?: string;
  createMethod?: RequestMethodEnum;
  updateUrl?: string;
  updateMethod?: RequestMethodEnum;
  deleteUrl?: string;
  deleteMethod?: RequestMethodEnum;
}
export default class CURD<T = any, K = any> {
  options: CURDApiOptions;
  constructor(options: CURDApiOptions) {
    options = Object.assign(
      {
        getDataMethod: RequestMethodEnum.POST,
        getPageMethod: RequestMethodEnum.POST,
        createMethod: RequestMethodEnum.POST,
        updateMethod: RequestMethodEnum.POST,
        deleteMethod: RequestMethodEnum.POST,
        getDetailMethod: RequestMethodEnum.POST,
      },
      options
    );
    this.options = options;
    if (!options.cudUrl) {
      if (!options.createUrl) {
        this.create = undefined;
      }
      if (!options.updateUrl) {
        this.update = undefined;
      }
      if (!options.deleteUrl) {
        this.delete = undefined;
      }
    }
    if (!options.getDetailUrl) {
      this.getDetail = undefined;
    }
  }
  getData(params?: K | SearchModel) {
    const method = (this.options.getDataMethod as string).toLowerCase();
    return req[method]<T[]>(
      {
        [this.options.getDataMethod === RequestMethodEnum.POST ? "data" : "params"]: params,
        url: this.options.getDataUrl,
      },
      {
        useGlobalLoading: false,
      }
    );
  }
  getPage(params: PaginationParam<K>) {
    if (!params.model) {
      params.model = {};
    }
    const method = (this.options.getPageMethod as string).toLowerCase();
    return req[method]<PaginationResult<T>>(
      {
        data: params,
        url: this.options.getPageUrl,
      },
      {
        useGlobalLoading: false,
      }
    );
  }
  getDetail?(params: any) {
    const method = (this.options.getDetailMethod as string).toLowerCase();
    return req[method]<T>(
      {
        [method === "get" ? "params" : "data"]: params,
        url: this.options.getDetailUrl,
      },
      {
        useGlobalLoading: false,
      }
    );
  }
  create?(params: T) {
    const method = this.options.createUrl ? (this.options.createMethod as string).toLowerCase() : "post";
    return req[method]<T>({
      [method === "get" ? "params" : "data"]: params,
      url: this.options.createUrl || this.options.cudUrl,
    });
  }
  update?(params: T) {
    const method = this.options.updateUrl ? (this.options.updateMethod as string).toLowerCase() : "post";
    return req[method]<T>({
      [method === "get" ? "params" : "data"]: params,
      url: this.options.updateUrl || this.options.cudUrl,
    });
  }
  delete?(params: DeleteParams) {
    const method = this.options.deleteUrl ? (this.options.deleteMethod as string).toLowerCase() : "post";
    return req[method]<boolean>({
      [method === "get" ? "params" : "data"]: params,
      url: this.options.deleteUrl || this.options.cudUrl,
    });
  }
}
